package nckd.wnqjt.tmc.tda.plugin.form;

import com.alibaba.fastjson.JSON;
import kd.bos.algo.*;
import kd.bos.algo.input.CollectionInput;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.entity.qing.*;
import kd.bos.entity.qing.Field;
import kd.bos.form.IPageCache;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 结算金额轻分析报表（个体折线图）
 */

public class TlementTrendQingQueryPlugin extends AbstractFormPlugin implements IQingDataProvider {

    private static final Logger log = LoggerFactory.getLogger(TlementTrendQingQueryPlugin.class);

    //组织形态
    private String[] orgType = {"部门","工厂","集团","集团公司","事业部"};

    @Override
    public QingMeta getMeta(String s) {
        String entityKey = "cas_recbill";
        QingMeta meta = new QingMeta();
        EntryEntity entity1 = new EntryEntity();
        entity1.setKey(entityKey);
        entity1.setName(new LocaleString("收款处理"));
        entity1.setPkFieldName("id");
        meta.addEntryEntity(entity1);

        Field column = new Field();
       /* column.setEntity(entityKey);//字段所属实体key	否
        column.setKey("id");// 字段名(唯一标识)	是
        column.setFieldType(QingFieldType.Int.toNumber()); //数据类型	是
        column.setName(new LocaleString("id")); //字段别名	是
        meta.addColumn(column);*/

        column = new Field();
        column.setEntity(entityKey);//字段所属实体key	否
        column.setKey("inflow");// 字段名(唯一标识)	是
        column.setFieldType(QingFieldType.Number.toNumber()); //数据类型	是
        column.setName(new LocaleString("本月流入")); //字段别名	是
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("outflow");
        column.setFieldType(QingFieldType.Number.toNumber());
        column.setName(new LocaleString("本月流出"));
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("claninflow");
        column.setFieldType(QingFieldType.Number.toNumber());
        column.setName(new LocaleString("本月净流入"));
        meta.addColumn(column);

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("month");
        column.setFieldType(QingFieldType.String.toNumber());
        column.setName(new LocaleString("月份"));
        meta.addColumn(column);

        /*column = new Field();
        column.setEntity(entityKey);
        column.setKey("orgName");
        column.setFieldType(QingFieldType.String.toNumber());
        column.setName(new LocaleString("组织"));
        meta.addColumn(column);*/

        column = new Field();
        column.setEntity(entityKey);
        column.setKey("siz");
        column.setFieldType(QingFieldType.Number.toNumber());
        column.setName(new LocaleString("计数字段"));
        meta.addColumn(column);
        return meta;
    }

    @Override
    public QingData getData(String s, int startRow, int i1) {
        long startTime = System.currentTimeMillis();

        String qFilter = getPageCache().get("qFilter");
        if (qFilter != null) {
            //通过此方法拿到过滤参数
            Map<String, Object> filterParam = (Map) JSON.parseObject(qFilter, Map.class);
        }
        QFilter[] billFilters = null;
        //单据状态=审核
        QFilter qFilter1 = new QFilter("billstatus", QCP.equals,"D");
        //结算方式为空
        QFilter settletnumberFilter = new QFilter("settletnumber", QCP.equals," ");

        List<String> orgNameList = new ArrayList<>();
        //查询辅助资料-股份下公司
        DynamicObject[] detail = BusinessDataServiceHelper.load("bos_assistantdata_detail", "id,name,group", new QFilter[]{new QFilter("group.id", QCP.equals, 2084821314140406784L)});
        if (detail.length > 0) {
            Arrays.asList(detail).forEach(d->{
                orgNameList.add(d.getString("name"));
            });
        }
        QFilter qFilter2 = new QFilter("org.name", QCP.in,orgNameList);

        //查账户查询基础资料
        DataSet bankDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "am_accountbank", "id,openorg.name as opName,bankaccountnumber,acctstatus", null, null);

        //查辅助资料
        DataSet detailDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "bos_assistantdata_detail", "id,name,group", new QFilter[]{new QFilter("group.id", QCP.equals, 2084821314140406784L)}, null);

        DynamicObject test = BusinessDataServiceHelper.newDynamicObject("nckd_testdocuments");
        test.set("billno","test-gufenz-" + new SimpleDateFormat("yyyyMMddHHmm").format(new Date()));
        test.set("billstatus","A");
        DynamicObjectCollection entryentity = test.getDynamicObjectCollection("entryentity");

        DataSet result = null;
        for (int i = 0; i < 12; i++) {

            String monthName = DateUtils.getMonthName(i);
            String month = "'"+monthName+"'";
            String month1 = monthName;
            /*
        收款单
         */
            QFilter dateQf = new QFilter("bizdate", QCP.large_equals, DateUtils.getMinMonth(i)).and(new QFilter("bizdate", QCP.less_equals, DateUtils.getMaxMonth(i)));
            billFilters = new QFilter[]{qFilter1,qFilter2,dateQf,settletnumberFilter};
            String recBillFiled = "id,billno,billstatus,actrecamt,settletnumber,org,org.id as recOrgId,org.name as orgName,payeedate,bizdate,payeracctbanknum,sourcebilltype";
            DataSet recBillData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_recbill", recBillFiled, billFilters, null);
            DataSet recBillData1 = recBillData.join(bankDataSet).on("payeracctbanknum", "bankaccountnumber").select(new String[]{"id", "billstatus", "billno", "settletnumber", "actrecamt", "recOrgId", "orgName", "payeedate", "bizdate", "payeracctbanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            recBillData1 = recBillData1.select("id", "billstatus", "billno", "settletnumber", "actrecamt", "recOrgId", "orgName", "payeedate", "bizdate", "payeracctbanknum","opName");
            recBillData1 = recBillData1.leftJoin(detailDataSet).on("opName","name").select(new String[]{"id", "billstatus", "billno", "settletnumber", "actrecamt", "recOrgId", "orgName", "payeedate", "bizdate", "payeracctbanknum","opName"},new String[]{"name"}).finish();
            recBillData1 = recBillData1.filter("name is null");
            DataSet recBillData2 = recBillData.leftJoin(bankDataSet).on("payeracctbanknum", "bankaccountnumber").select(new String[]{"id", "billstatus", "billno", "settletnumber", "actrecamt", "recOrgId", "orgName", "payeedate", "bizdate", "payeracctbanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            recBillData2 = recBillData2.filter("bankaccountnumber is null").addField("null","name").select("id", "billstatus", "billno", "settletnumber", "actrecamt", "recOrgId", "orgName", "payeedate", "bizdate", "payeracctbanknum","opName","name");
            recBillData1 = recBillData1.union(recBillData2);
            recBillData1 = recBillData1.select("id,actrecamt,billno");

            /**
             * 收款单-业务处理
             */
            QFilter sourceFilter = new QFilter("sourcebilltype",QCP.equals,"cdm_drafttradebill");
            billFilters = new QFilter[]{qFilter1,qFilter2,dateQf, sourceFilter};
            DataSet sourceRecBillData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_recbill", recBillFiled, billFilters, null);
            recBillData1 = sourceRecBillData.select("id,actrecamt,billno").union(recBillData1).distinct();
            //打印单据
            DataSet sourceRecData = recBillData1.copy();
            while (sourceRecData.hasNext()) {
                DynamicObject entry = entryentity.addNew();
                Row row = sourceRecData.next();
                entry.set("nckd_name", "收款单");
                entry.set("nckd_number", row.get("billno"));
                entry.set("nckd_amount", row.get("actrecamt"));
            }

            DataSet groupRecBillData = recBillData1.groupBy().sum("actrecamt").finish();
            groupRecBillData = groupRecBillData.select("actrecamt,0 as actpayamt,0 as actpayamount");

        /*
        付款单-付款日期
         */
            QFilter channelFilter = new QFilter("paymentchannel", QCP.equals, "bei");
            dateQf = new QFilter("paydate", QCP.large_equals, DateUtils.getMinMonth(i)).and(new QFilter("paydate", QCP.less_equals, DateUtils.getMaxMonth(i)));
            billFilters = new QFilter[]{qFilter1, qFilter2,dateQf,settletnumberFilter,channelFilter};
            String payBillFiled = "id,billno,billstatus,settletnumber,org,org.id as payOrgId,org.name as orgName,paydate,actpayamt,paymentchannel,bizdate,payeebanknum,sourcebilltype";
            DataSet renPayBillData1 = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_paybill", payBillFiled, billFilters, null);
            DataSet payBillData1 = renPayBillData1.join(bankDataSet).on("payeebanknum", "bankaccountnumber").select(new String[]{"id","billno", "actpayamt", "payeebanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            payBillData1 = payBillData1.select("id","billno", "actpayamt", "payeebanknum","opName");
            payBillData1 = payBillData1.leftJoin(detailDataSet).on("opName","name").select(new String[]{"id","billno", "actpayamt", "payeebanknum","opName"},new String[]{"name"}).finish();
            payBillData1 = payBillData1.filter("name is null");
            DataSet payBillData3 = renPayBillData1.leftJoin(bankDataSet).on("payeebanknum", "bankaccountnumber").select(new String[]{"id","billno", "actpayamt", "payeebanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            payBillData3 = payBillData3.filter("bankaccountnumber is null").addField("null","name").select("id","billno", "actpayamt", "payeebanknum","opName","name");
            payBillData1 = payBillData1.union(payBillData3);
            payBillData1 = payBillData1.select("id,actpayamt,billno");


            /*
        付款单-业务日期
         */
            channelFilter = new QFilter("paymentchannel", QCP.equals, "onlinebank").or(new QFilter("paymentchannel", QCP.equals, "counter"));
            dateQf = new QFilter("bizdate", QCP.large_equals, DateUtils.getMinMonth(i)).and(new QFilter("bizdate", QCP.less_equals, DateUtils.getMaxMonth(i)));
            billFilters = new QFilter[]{qFilter1, qFilter2,dateQf,settletnumberFilter,channelFilter};
            DataSet renPayBillData2 = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_paybill", payBillFiled, billFilters, null);
            DataSet payBillData2 = renPayBillData2.join(bankDataSet).on("payeebanknum", "bankaccountnumber").select(new String[]{"id","billno", "actpayamt", "payeebanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            payBillData2 = payBillData2.select("id","billno", "actpayamt", "payeebanknum","opName");
            payBillData2 = payBillData2.leftJoin(detailDataSet).on("opName","name").select(new String[]{"id","billno", "actpayamt", "payeebanknum","opName"},new String[]{"name"}).finish();
            payBillData2 = payBillData2.filter("name is null");
            DataSet payBillData4 = renPayBillData2.leftJoin(bankDataSet).on("payeebanknum", "bankaccountnumber").select(new String[]{"id","billno", "actpayamt", "payeebanknum"}, new String[]{"bankaccountnumber", "opName"}).finish();
            payBillData4 = payBillData4.filter("bankaccountnumber is null").addField("null","name").select("id","billno", "actpayamt", "payeebanknum","opName","name");
            payBillData2 = payBillData2.union(payBillData4);
            payBillData2 = payBillData2.select("id,actpayamt,billno");


            /**
             * 付款单-业务处理
             */
            billFilters = new QFilter[]{qFilter1,qFilter2,dateQf,sourceFilter};
            DataSet payBillData5 = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_paybill", payBillFiled, billFilters, null);
            DataSet payBillData = payBillData5.select("id,actpayamt,billno").union(payBillData1).union(payBillData2).distinct();

            //打印单据
            DataSet payCopy1 = payBillData.copy();
            while (payCopy1.hasNext()) {
                DynamicObject entry = entryentity.addNew();
                Row row = payCopy1.next();
                entry.set("nckd_name", "付款单"+month1);
                entry.set("nckd_number", row.get("billno"));
                entry.set("nckd_amount", row.get("actpayamt"));
            }

            payBillData = payBillData.groupBy().sum("actpayamt").finish().select("0 as actrecamt,actpayamt,0 as actpayamount");

        /*
        代发单
         */
            String agentBillFiled = "id,billno,billstatus,actpayamount,settletnumber,org,org.id as agentOrgId,org.name as orgName,paytime";
            dateQf = new QFilter("paytime", QCP.large_equals, DateUtils.getMinMonth(i)).and(new QFilter("paytime", QCP.less_equals, DateUtils.getMaxMonth(i)));
            billFilters = new QFilter[]{qFilter1,qFilter2,dateQf,settletnumberFilter};
            DataSet agentBillData = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cas_agentpaybill", agentBillFiled, billFilters, null);

            //打印单据
            DataSet agentCopy = agentBillData.copy();
            while (agentCopy.hasNext()) {
                DynamicObject entry = entryentity.addNew();
                Row row = agentCopy.next();
                entry.set("nckd_name", "代发单"+month1);
                entry.set("nckd_number", row.get("billno"));
                entry.set("nckd_amount", row.get("actpayamount"));
            }

            agentBillData = agentBillData.groupBy().sum("actpayamount").finish().select("0 as actrecamt,0 as actpayamt,actpayamount");


            DataSet dataSet2 = groupRecBillData.union(payBillData).union(agentBillData);
            dataSet2 = dataSet2.groupBy().sum("actrecamt").sum("actpayamt").sum("actpayamount").finish();
            dataSet2 = dataSet2.addField(month,"month").addField(String.valueOf(i),"siz");
            dataSet2 = dataSetDefaultValue(dataSet2,month1,String.valueOf(i));
            if (result == null){
                result = dataSet2;
            }else {
                result = result.union(dataSet2);
            }
        }
        SaveServiceHelper.save(new DynamicObject[]{test});

        QingData data = null;
        if (startRow < 200) {
            data = new QingData();
            Map<String, Integer> dataindex = new HashMap<String, Integer>();
            dataindex.put("inflow", 0);
            dataindex.put("outflow", 1);
            dataindex.put("claninflow", 2);
            dataindex.put("month", 3);
            dataindex.put("siz", 4);
            data.setDataindex(dataindex);

            List<Object[]> rows = new ArrayList<Object[]>();
            while (result.hasNext()) {
                Row row = result.next();
                Object[] obj = new Object[5];
                BigDecimal actrecamt = row.getBigDecimal("actrecamt") == null ? BigDecimal.ZERO : row.getBigDecimal("actrecamt");
                BigDecimal actpayamt = row.getBigDecimal("actpayamt") == null ? BigDecimal.ZERO : row.getBigDecimal("actpayamt");
                BigDecimal actpayamount = row.getBigDecimal("actpayamount") == null ? BigDecimal.ZERO : row.getBigDecimal("actpayamount");
                obj[0] = actrecamt;
                obj[1] = actpayamt.add(actpayamount);
                obj[2] = actrecamt.subtract(actpayamt.add(actpayamount));
                obj[3] = row.getString("month");
                obj[4] = row.getInteger("siz");
                rows.add(obj);
            }
            data.setRows(rows);
        }
        long endTime = System.currentTimeMillis();
        log.info("股份折线图耗费时间" + (endTime-startTime) + "ms");
        return data;
    }

    private DataSet dataSetDefaultValue(DataSet dataSet, String month ,String siz) {
        if (dataSet.isEmpty()) {
            // 创建一个空的DataSet
            Collection<Object[]> coll = new ArrayList<>();
            Object[] objects = {BigDecimal.ZERO,BigDecimal.ZERO,BigDecimal.ZERO,month,siz};
            coll.add(objects);
            String[] fields = new String[]{"actrecamt", "actpayamt", "actpayamount", "month", "siz"};
            DataType[] dataTypes = new DataType[]{DataType.BigDecimalType,DataType.BigDecimalType,DataType.BigDecimalType,DataType.StringType,DataType.IntegerType};
            RowMeta rowMeta = RowMetaFactory.createRowMeta(fields, dataTypes);
            CollectionInput inputs = new CollectionInput(rowMeta, coll);
            dataSet = Algo.create(this.getClass().getName()).createDataSet(inputs);
        }
        return dataSet;
    }

    @Override
    public void setFilterParameter(String filterParameter) {
        IPageCache pageCache = getPageCache();
        pageCache.put("qFilter", filterParameter);

    }

    @Override
    public String getFilterParameter() {
        return getPageCache().get("qFilter");
    }





}
